iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 7
0
自我挑戰組

React初心者30天的探索之路系列 第 7

[Day 07] Functional Component v.s Class Component

  • 分享至 

  • xImage
  •  

原本以為只有Class Component的寫法,但在看技術文章的時候發現還有一種寫法是Function component,有了React Hook之後,好像Function Component就變成主流了(嗎)?

那Class component 跟 Functional component差在哪裡?

一個比較冗長一個比較簡單

Class component

  • 需繼承React.Component
  • 具有生命週期,可以針對某些情境決定是否渲染,ex shouldComponentUpdate()
  • 具有state (Stateful component)
  • 需要實作render方法
  • 擁有this
  • 每次都可以拿到最新的this.props,因為this隨時都在變化,

Functional component

  • 沒有生命週期 (React Hook userEffect 出現後,就有生命週期了!)
  • 沒有state(Stateless),所以被稱為無狀態組件(但React Hook useState出現後就可以有state了!)
  • 可以用arrow function 宣告或是一般的function
  • 沒有this
  • 編譯更快(因為不用將class轉換成es5
  • props會一直是原本傳進來的那個,而不會跟著更新,閉包的概念

那麼在還沒出現React Hook之前,是什麼情境下會用到Functional Component呢?假設Component不需要紀錄狀態(state),只是單純地處理一些UI繪製,就可以用Functional Component

來試著簡單寫一個Functional Component,但暫時不用hooks(這部分後續會再介紹)

function Functional(props) {
    const sayHi =()=>{
        console.log('hi')
    }
    return <button onClick={sayHi}>btn</button>
}

用arrow function的話,連return都不用寫,看起來真的變得很簡短

const Functional = ({ props }) => (<button>props</button>)

而且Functional Component跟Class Component經過babel的編譯,轉換成ES5的程式碼的大小差距真的有讓我嚇一跳,查到一個數據是100bytes v.s 1.2kb

有了React Hooks之後,Functional Component也能擁有跟Class Component一樣的功能,而且更簡短的寫法可以少掉不少程式碼,可讀性也更高,讓Functional Component成為當前React開發的主流。

另外還有一種component叫做pure component,範例如下,點擊click後數字會+1

import React, { Component, Fragment } from 'react';

class InfoBox extends Component{
    render(){
        console.log("InfoBox render")
        return(
            <Fragment>
                {this.props.isShow ? <p>yo!!!!</p> : null}
            </Fragment>
        )
    }
}
class PureExamle extends Component{
    state = {
        count:0,
        isShow:false
    }
    handleClick = () =>{
        this.setState({count: this.state.count + 1} )
    }
    render(){
        console.log("PureExamle render")
        return(
            <Fragment>
                <h1>{this.state.count}</h1>
                <button onClick={this.handleClick}>click</button>
                <InfoBox isShow={this.state.isShow} />
            </Fragment>
        )
    }
}

export default PureExamle

接者我點擊了三次加1的按鈕,恩?好像哪裡怪怪的?為什麼我修改count,state沒變,infobox 這個component也要跟著重新渲染?

這時就可以用PureComponent來避免不必要的渲染,引用PureComponent並且繼承PureComponent

import React, { Component, PureComponent, Fragment } from 'react';

class InfoBox extends PureComponent{
    render(){
        console.log("InfoBox render")
        return(
            <Fragment>
                {this.props.isShow ? <p>yo!!!!</p> : null}
            </Fragment>
        )
    }
}

再看console log就會發現只會印出PureExample render了!

參考資料:How Are Function Components Different from Classes?


上一篇
[Day 06] 一磚一瓦-React Component
下一篇
[Day 08] React lifeCycle 生命週期
系列文
React初心者30天的探索之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言